import java.util.concurrent.*;
/**********************************************************************
 * 
 *  Concurrent Programming
 *  
 *  Exercise 2.1
 * 
 *  Identify critical sections and use a semaphore
 *  	
 *    Solution:
 *  	 A critical section is a piece of code that uses a shared resource (e.g. global variable). In this case, whenever we call the operations
 *       addRow and deleteRow methods it is a critical section. That is because the operations use global variables: display and usedRows, to update the display.
 *  	 Because the methods are not thread safe we guarantee mutual exclusion by using a semaphore.
 *       We acquire the semaphore whenever we call one of the operations and release it after the execution of the operation.  
 * 	
 * 	Exercise 2.2
 * 		
 * 	Make the implementation of the JDisplay2 thread safe.
 *   
 *   Solution:
 *   	Put synchronization to the header of each method.
 * 
 **********************************************************************/

public class Main3_Semaphore {

   private static Semaphore sem = new Semaphore(1,true);
	
   private static void nap(int millisecs) {
        try {
            Thread.sleep(millisecs);
        } catch (InterruptedException e) {
            System.err.println(e.getMessage());
        }
    }

    private static void addProc(HighLevelDisplay d) {
    	try{
	    	sem.acquire();
	    	d.addRow("EvilChi_1");
	    	sem.release();
	    	
	    	nap(50);
	    	
	    	sem.acquire();
	    	d.addRow("EvilChi_2");
	    	sem.release();
	    	
	    	sem.acquire();
	    	d.addRow("EvilChi_3");
	    	sem.release();
	    	
	    	nap(200);
	    	
	    	sem.acquire();
	    	d.addRow("EvilChi_4");
	    	sem.release();
	    	
	    	
	// Add a sequence of addRow operations with short random naps.
    	}catch(InterruptedException e){
    		
    		
    	}
   }

    private static void deleteProc(HighLevelDisplay d) {
    	
    	try{
    		nap(60);
    		
	    	sem.acquire();
	    	d.deleteRow(0);
	    	sem.release();
	    	
	    	nap(5000);
	    	
	    	sem.acquire();
	    	d.deleteRow(0);
	    	sem.release();
	    	
	    	nap(400);
	    	
    	}catch(InterruptedException e){
    		
    
    	}
	// Add a sequence of deletions of row 0 with short random naps.
    }

    public static void main(String [] args) {
	final HighLevelDisplay d = new JDisplay2();

	new Thread () {
	    public void run() {
		addProc(d);
	    }
	}.start();


	new Thread () {
	    public void run() {
		deleteProc(d);
	    }
	}.start();

    }
}